package com.ruoyi.web.controller.wechat;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.ruoyi.common.constant.wechat.WechatConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.wechat.WechatUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.exception.user.UserException;
import com.ruoyi.common.sms.SmsUtil;
import com.ruoyi.system.domain.wechat.request.vo.CreateForWechatUserVO;
import com.ruoyi.system.domain.wechat.request.vo.FilterForWechatUserListVO;
import com.ruoyi.system.domain.wechat.request.vo.WechatUserForgetPasswordVO;
import com.ruoyi.system.domain.wechat.request.vo.WechatUserRegisterVO;
import com.ruoyi.system.mapper.wechat.WechatRoleMapper;
import com.ruoyi.system.service.wechat.IWechatPostService;
import com.ruoyi.system.service.wechat.IWechatUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import javax.validation.constraints.Size;
import java.util.concurrent.TimeUnit;

/**
 * 微信小程序用户
 *
 * @author jiexiang.sun/Jason
 * @version 1.0.0
 * @create 2022-03-03 19:34
 **/
@RestController
@Validated
@RequestMapping("/wechat/user")
public class WechatUserController extends BaseController {

    @Autowired
    private IWechatUserService wechatUserService;

    @Autowired
    private IWechatPostService wechatPostService;

    @Autowired
    private WechatRoleMapper wechatRoleMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 用户登录
     *
     * @param phonenumber 手机号码：非空判断
     * @param password    密码（明文）：非空判断
     * @return
     */
    @GetMapping("/login")
    public AjaxResult login(@NotBlank(message = "请输入手机号码") @Size(min = 11, max = 11, message = "请输入正确手机号码") @Positive(message = "请输入正确手机号码") String phonenumber
            , @NotBlank(message = "请输入密码") String password) {
        LambdaQueryWrapper<WechatUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WechatUser::getPhonenumber, phonenumber)
                .eq(WechatUser::getPassword, SecureUtil.md5(password))
                .eq(WechatUser::getDelFlag, UserStatus.OK.getCode())
                .ne(WechatUser::getDeleteAudit, UserStatus.DELETED.getCode());
        WechatUser wechatUser = wechatUserService.getOne(lambdaQueryWrapper);
        if (ObjectUtil.isEmpty(wechatUser)) {
            throw new UserException("wechat.user.not.exist.or.password.not.incorrect", null);
        }

        if (!wechatUser.accountNormal()) {
            throw new UserException("wechat.user.not.verified", null);
        }

        Long tokenId = IdUtil.getSnowflakeNextId();
        redisCache.setCacheObject(WechatConstants.WECHAT_TOKEN_KEY_PREFIX + tokenId, wechatUser.getUserId(), 1, TimeUnit.DAYS);

        return AjaxResult.success(tokenId);
    }

    /**
     * 用户注册
     *
     * @param params
     * @return
     */
    @PostMapping("register")
    public AjaxResult register(@Validated @RequestBody WechatUserRegisterVO params) {
        if (wechatUserService.register(params)) {
            return AjaxResult.success("注册成功");
        }
        return AjaxResult.error("注册失败");
    }

    /**
     * 获取用户列表
     *
     * @param params
     * @return
     */
    @GetMapping("list")
    public TableDataInfo list(@RequestAttribute(name = WechatConstants.WECHAT_TOKEN_USER_DEPTID) Long deptId, FilterForWechatUserListVO params) {
        params.setDeptId(deptId);
        params.setIncludeSelfDept((short) 1);
        PageHelper.startPage(params.getPageNum(), params.getPageSize());
        return getDataTable(wechatUserService.list(params));
    }

    /**
     * 创建我的下级用户
     *
     * @return
     */
    @PostMapping("createUser")
    public AjaxResult createUser(@RequestBody CreateForWechatUserVO params) {
        return AjaxResult.success(wechatUserService.create(params));
    }

    /**
     * 删除用户账号
     *
     * @param userId
     * @return
     */
    @DeleteMapping("{userId}")
    public AjaxResult remove(@PathVariable Long userId) {
        return AjaxResult.success(wechatUserService.applyDelete(userId));
    }

    /**
     * 获取我的个人信息
     *
     * @param userId
     * @return
     */
    @GetMapping("/getMyInfo")
    public AjaxResult getMyInfo(@NotNull(message = "用户不存在") @RequestAttribute(name = WechatConstants.WECHAT_TOKEN_USERID) Long userId) {
        return AjaxResult.success(wechatUserService.info(userId));
    }

    @Value("${sms.template.register.captcha}")
    private String SmsTemplateByRegister;

    /**
     * 用户账号注册获取短信验证码
     *
     * @param phonenumber 接收短信验证码的手机号码
     * @return
     */
    @GetMapping("register/getCaptcha")
    public AjaxResult getRegisterCaptcha(@NotBlank(message = "请输入手机号码") @Size(min = 11, max = 11, message = "请输入正确手机号码") @Positive(message = "请输入正确手机号码") String phonenumber) {
        LambdaQueryWrapper<WechatUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WechatUser::getPhonenumber, phonenumber)
                .eq(WechatUser::getDelFlag, UserStatus.OK.getCode());

        if (wechatUserService.count(lambdaQueryWrapper) > 0) {
            throw new UserException("wechat.mobile.number.is.already.registered", null);
        }

        String code = RandomUtil.randomNumbers(6);

        try {
            String smsResult = SmsUtil.sendMessage(phonenumber, StrUtil.format(SmsTemplateByRegister, code));
            if (JSONObject.parseObject(smsResult).getBoolean("success")) {
                // 将验证码写入缓存，5分钟有效
                redisCache.setCacheObject(WechatConstants.WECHAT_ACCOUNT_REGISTER_CAPTCHA_CACHE_KEY_PREFIX + phonenumber, code, 5, TimeUnit.MINUTES);
                return AjaxResult.success();
            }else{
                throw new UserException("wechat.register.captcha.send.fail", null);
            }
        } catch (Exception exception) {
            throw new UserException("wechat.register.captcha.send.fail", null);
        }
    }

    @Value("${sms.template.forgetPassowrd.captcha}")
    private String SmsTemplateByForgetPassowrd;

    /**
     * 用户找回密码获取短信验证码
     *
     * @param phonenumber 接收短信验证码的手机号码
     * @return
     */
    @GetMapping("forgetPassowrd/getCaptcha")
    public AjaxResult getForgetPasswordCaptcha(@NotBlank(message = "请输入手机号码") @Size(min = 11, max = 11, message = "请输入正确手机号码") @Positive(message = "请输入正确手机号码") String phonenumber) {
        LambdaQueryWrapper<WechatUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WechatUser::getPhonenumber, phonenumber)
                .eq(WechatUser::getDelFlag, UserStatus.OK.getCode());

        if (wechatUserService.count(lambdaQueryWrapper) <= 0) {
            throw new UserException("wechat.user.not.exist", null);
        }

        String code = RandomUtil.randomNumbers(6);
        try {
            String smsResult = SmsUtil.sendMessage(phonenumber, StrUtil.format(SmsTemplateByForgetPassowrd, code));
            if (JSONObject.parseObject(smsResult).getBoolean("success")) {
                // 将验证码写入缓存，5分钟有效
                redisCache.setCacheObject(WechatConstants.WECHAT_ACCOUNT_FORGET_PASSWORD_CAPTCHA_CACHE_KEY_PREFIX + phonenumber, code, 5, TimeUnit.MINUTES);
                return AjaxResult.success();
            }else{
                throw new UserException("wechat.forgetPassowrd.captcha.send.fail", null);
            }
        } catch (Exception exception) {
            throw new UserException("wechat.forgetPassowrd.captcha.send.fail", null);
        }
    }

    /**
     * 修改密码
     *
     * @param params
     * @return
     */
    @PostMapping("modifyPassword")
    public AjaxResult modifyPassword(@Validated @RequestBody WechatUserForgetPasswordVO params) {
        if (wechatUserService.modifyPassword(params)) {
            return AjaxResult.success("密码修改成功");
        }
        return AjaxResult.error("密码修改失败");
    }

    /**
     * 编辑头像
     *
     * @param avatar
     * @param userId
     * @return
     */
    @PutMapping("avatar")
    public AjaxResult putAvatar(@RequestParam(required = false, name = "avatar") String avatar
            , @RequestAttribute(name = WechatConstants.WECHAT_TOKEN_USERID) Long userId) {
        WechatUser user = new WechatUser();
        user.setUserId(userId);
        user.setAvatar(StrUtil.isBlank(avatar) ? "" : avatar);
        return AjaxResult.success(wechatUserService.updateById(user) ? "编辑头像成功" : "编辑头像失败");
    }
}
